 /*******************************************************************************
  * Copyright (c) 2003, 2006 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
  *
  * Contributors:
  * IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.ui.navigator;

 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.jface.util.LocalSelectionTransfer;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.swt.dnd.DropTargetEvent;
 import org.eclipse.swt.dnd.TransferData;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.ui.internal.navigator.NavigatorContentService;

 /**
  * <p>
  * Used by the
  * <b>org.eclipse.ui.navigator.navigatorContent/navigatorContent/commonDropAdapter</b>
  * extension point to carry out pluggable drop operations.
  * </p>
  * <p>
  * Each {@link CommonDropAdapterAssistant} is contained by single content
  * extension. The opportunity for each assistant to handle the drop operation is
  * determined by the <b>possibleChildren</b> expression of the
  * <b>org.eclipse.ui.navigator.navigatorContent/navigatorContent</b> extension;
  * whenever every element in the drag set matches the <b>possibleChildren</b>
  * expression of an extension, it is eligible to handle the drop operation. This
  * initial set is further culled using the <b>possibleDropTargets</b>
  * expression of the <b>commonDropAdapter</b> using the current drop target.
  * </p>
  * <p>
  * If drag operations originate outside of Eclipse, then the set of eligible
  * drop adapters is determined based on the drop target (using the
  * <b>possibleDropTargets</b> expression). Each assistant can then indicate
  * whether {@link #isSupportedType(TransferData) the incoming type is supported}.
  * <p>
  * Whenever a match is found, the assistant will be given an opportunity to
  * first {@link #validateDrop(Object, int, TransferData)}, and then if the
  * assistant returns true, the assist must
  * {@link #handleDrop(CommonDropAdapter, DropTargetEvent, Object)}. If
  * multiple assistants match the drop target, then the potential assistants are
  * ordered based on priority and their override relationships and given an
  * opportunity to validate the drop operation in turn. The first one to validate
  * will have the opportunty to carry out the drop.
  * </p>
  *
  * <p>
  * Clients may handle DND operations that begin and end in the current viewer by
  * overriding the following methods:
  * <ul>
  * <li>{@link #validateDrop(Object, int, TransferData)}: Indicate whether this
  * assistant can handle a drop onto the current viewer.</li>
  * <li>{@link #handleDrop(CommonDropAdapter, DropTargetEvent, Object)}: Handle
  * the drop operation onto the current viewer.</li>
  * </ul>
  * </p>
  * <p>
  * If a user originates a drag operation to another viewer that cannot handle
  * one of the available drag transfer types, drop assistants may handle the drop
  * operation for the target viewer. Clients must override :
  * <ul>
  * <li>{@link #validatePluginTransferDrop(IStructuredSelection, Object)}:
  * Indicate whether this assistant can handle the drop onto another viewer.
  * <li>{@link #handlePluginTransferDrop(IStructuredSelection, Object)}: Handle
  * the drop operation onto the other viewer.</li>
  * </ul>
  * </p>
  * <p>
  * Clients may implement this interface.
  * </p>
  *
  * @see INavigatorDnDService
  * @see INavigatorDnDService#findCommonDropAdapterAssistants(Object,
  * TransferData)
  * @since 3.2
  *
  */
 public abstract class CommonDropAdapterAssistant {

     private INavigatorContentService contentService;

     /**
      * Perform any necessary initialization using the
      * {@link INavigatorContentService}.
      *
      *
      * @param aContentService
      * The instance of {@link INavigatorContentService} that the
      * current CommonDropAdapterAssistant will be associated with
      */
     public final void init(INavigatorContentService aContentService) {
         contentService = aContentService;
         doInit();
     }

     /**
      * Override to perform any one-time initialization.
      */
     protected void doInit() {

     }

     /**
      * Validates dropping on the given object. This method is called whenever
      * some aspect of the drop operation changes.
      * <p>
      * Subclasses must implement this method to define which drops make sense.
      * If clients return true, then they will be allowed to handle the drop in
      * {@link #handleDrop(CommonDropAdapter, DropTargetEvent, Object) }.
      * </p>
      *
      * @param target
      * the object that the mouse is currently hovering over, or
      * <code>null</code> if the mouse is hovering over empty space
      * @param operation
      * the current drag operation (copy, move, etc.)
      * @param transferType
      * the current transfer type
      * @return A status indicating whether the drop is valid.
      */
     public abstract IStatus validateDrop(Object target, int operation,
             TransferData transferType);

     /**
      * Carry out the DND operation.
      *
      * @param aDropAdapter
      * The Drop Adapter contains information that has already been
      * parsed from the drop event.
      * @param aDropTargetEvent
      * The drop target event.
      * @param aTarget
      * The object being dragged onto
      * @return A status indicating whether the drop completed OK.
      */
     public abstract IStatus handleDrop(CommonDropAdapter aDropAdapter,
             DropTargetEvent aDropTargetEvent, Object aTarget);

     /**
      * Clients may extend the supported transfer types beyond the default
      * {@link LocalSelectionTransfer#getTransfer()} and
      * {@link org.eclipse.ui.part.PluginTransfer#getInstance()} transfer types. When a transfer type
      * other than one of these is encountered, the DND Service will query the
      * <b>visible</b> and <b>active</b> descriptors that are <b>enabled</b>
      * for the drop target of the current operation.
      *
      * @param aTransferType
      * The transfer data from the drop operation
      * @return True if the given TransferData can be understood by this
      * assistant.
      */
     public boolean isSupportedType(TransferData aTransferType) {
         return LocalSelectionTransfer.getTransfer().isSupportedType(
                 aTransferType);
     }

     /**
      *
      * Return true if the client can handle the drop onto the target viewer of
      * the drop operation.
      * <p>
      * The default behavior of this method is to return <b>Status.CANCEL_STATUS</b>.
      * </p>
      *
      * @param aDragSelection
      * The selection dragged from the viewer.
      * @param aDropTarget
      * The target of the drop operation.
      *
      * @return OK if the plugin transfer can be handled by this assistant.
      */
     public IStatus validatePluginTransferDrop(
             IStructuredSelection aDragSelection, Object aDropTarget) {
         return Status.CANCEL_STATUS;
     }

     /**
      * Handle the drop operation for the target viewer.
      * <p>
      * The default behavior of this method is to return <b>Status.CANCEL_STATUS</b>.
      * </p>
      *
      * @param aDragSelection
      * The selection dragged from the viewer.
      * @param aDropTarget
      * The target of the drop operation.
      *
      * @return OK if the drop operation succeeded.
      */
     public IStatus handlePluginTransferDrop(
             IStructuredSelection aDragSelection, Object aDropTarget) {
         return Status.CANCEL_STATUS;
     }

     /**
      *
      * @return The associated content service.
      */
     protected INavigatorContentService getContentService() {
         return contentService;
     }

     /**
      *
      * @return A shell for the viewer currently used by the
      * {@link INavigatorContentService}.
      */
     protected final Shell getShell() {
         return ((NavigatorContentService) contentService).getShell();
     }

 }

